﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace Tambourine.Model
{
    /// <summary>
    /// Presents one row in pivot table.
    /// Object with dynamic props;
    /// </summary>
    public class TestCortege : ICustomTypeDescriptor
    {
        Dictionary<string, object> values = new Dictionary<string, object>();

        public object this[string key]
        {
            get
            {
                object value;
                values.TryGetValue(key, out value);
                return value;
            }
            set
            {
                if (value == null) values.Remove(key);
                else values[key] = value;
            }
        }

        #region ICustomTypeDescriptor

        AttributeCollection ICustomTypeDescriptor.GetAttributes() { return TypeDescriptor.GetAttributes(this, true); }
        string ICustomTypeDescriptor.GetClassName() { return TypeDescriptor.GetClassName(this, true); }
        string ICustomTypeDescriptor.GetComponentName() { return TypeDescriptor.GetComponentName(this, true); }
        TypeConverter ICustomTypeDescriptor.GetConverter() { return TypeDescriptor.GetConverter(this, true); }
        EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() { return TypeDescriptor.GetDefaultEvent(this, true); }
        PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() { return TypeDescriptor.GetDefaultProperty(this, true); }
        object ICustomTypeDescriptor.GetEditor(Type editorBaseType) { return TypeDescriptor.GetEditor(this, editorBaseType, true); }
        EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { return TypeDescriptor.GetEvents(this, true); }
        EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) { return TypeDescriptor.GetEvents(this, attributes, true); }
        PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() { return ((ICustomTypeDescriptor)this).GetProperties(null); }
        object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) { return this; }

        PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
        {
            var dynamicDescriptors = new PropertyDescriptor[0];

            dynamicDescriptors =
                this.values.Keys
                .Select(p => new TestCortegePropertyDescriptor(p,this.values[p].GetType()))
                .Cast<PropertyDescriptor>()
                .ToArray();

            return new PropertyDescriptorCollection(dynamicDescriptors);
        }

        #endregion ICustomTypeDescriptor
    }

    public class TestCortegePropertyDescriptor : PropertyDescriptor
    {
        Type type;

        public TestCortegePropertyDescriptor(string name, Type t = null) : base(name, null) { type = t; }
        public override bool CanResetValue(object component) { return false; }
        public override object GetValue(object component) { return ((TestCortege)component)[Name]; }
        public override void ResetValue(object component) { }
        public override void SetValue(object component, object value) { ((TestCortege)component)[Name] = value; }
        public override bool ShouldSerializeValue(object component) { return false; }
        public override Type ComponentType { get { return typeof(object); } }
        public override bool IsReadOnly { get { return false; } }
        public override Type PropertyType { get { return type ?? typeof(object); } }
    }
}